/* Includes ------------------------------------------------------------------*/
#include "MyApplication.h"

/* Private define-------------------------------------------------------------*/

/* Private variables----------------------------------------------------------*/
static void Measure_Period_Mode(void);
static uint8_t CRC_8(uint8_t *,uint8_t );
/* Public variables-----------------------------------------------------------*/
SHT30_t SHT30 = 
{
    0.0,
    0,
    Measure_Period_Mode
};
/* Private function prototypes------------------------------------------------*/

/*
* @name   Measure_Period_Mode
* @brief  SHT30周期测量模式
* @param  None
* @retval None   
*/
static void Measure_Period_Mode()
{
    uint8_t temp_array[6] = {0};
    uint16_t temp_uint    = 0;
    float    temp_float   = 0.0;

    //设置周期测量模式
    IIC_Soft.IIC_Start();
    IIC_Soft.Write_Byte(SHT30_ADDR&WRITE_CMD);
    IIC_Soft.ReciveACK();
    IIC_Soft.Write_Byte(0x27);  //high repeat，mps = 10
    IIC_Soft.ReciveACK();
    IIC_Soft.Write_Byte(0x37);
    IIC_Soft.ReciveACK();

    //读取数据
    Timer6.SHT30_Measure_Timeout = 0;
    do
    {
        //如果2秒内没有获取到数据，则break退出
        if(Timer6.SHT30_Measure_Timeout >= TIMER_2s)
        {
            LED.LED_Fun(LED2,LED_OFF);
            break;
        }
        IIC_Soft.IIC_Start();
        IIC_Soft.Write_Byte(SHT30_ADDR&WRITE_CMD);
        IIC_Soft.ReciveACK();
        //0xE000是向SHT30取数据的指令，主机发送该指令后开始读取SHT30的温湿度数据
        IIC_Soft.Write_Byte(0xE0);  
        IIC_Soft.ReciveACK();
        IIC_Soft.Write_Byte(0x00);
        IIC_Soft.ReciveACK();
        //重新发送起始信号，往SHT30发送地址加读取数据指令
        IIC_Soft.IIC_Start();
        IIC_Soft.Write_Byte(SHT30_ADDR|READ_CMD);
    /*判断是否收到从机应答，主机收到NACK时，继续循环发送取数据指令，主机收到ACK时，不满足
    条件，退出，往下执行*/
    } while (IIC_Soft.ReciveACK() == NACK); 
    
    //接收温湿度数据
    //判断是否是超时退出，如果不是，则有数据，进行接收；如果是则没有数据，不处理
    if(Timer6.SHT30_Measure_Timeout < TIMER_2s)
    {
        temp_array[0] = IIC_Soft.Recive_Byte();IIC_Soft.SendACK(ACK);
        temp_array[1] = IIC_Soft.Recive_Byte();IIC_Soft.SendACK(ACK);
        temp_array[2] = IIC_Soft.Recive_Byte();IIC_Soft.SendACK(ACK);
        temp_array[3] = IIC_Soft.Recive_Byte();IIC_Soft.SendACK(ACK);
        temp_array[4] = IIC_Soft.Recive_Byte();IIC_Soft.SendACK(ACK);
        temp_array[5] = IIC_Soft.Recive_Byte();IIC_Soft.SendACK(NACK);
        IIC_Soft.IIC_Stop();

        //计算温度
        if(CRC_8(temp_array,2) == temp_array[2])                //进行CRC-8校验
        {
            temp_uint = temp_array[0]*256+temp_array[1];        //取出16位的温度值
            temp_float = ((float)temp_uint)*0.267032-4500;    //根据手册公式计算，为了精度，计算数值先*100
            SHT30.fTemperature = temp_float*0.01;             //再除以100，得到正常温度值
        }

        //计算湿度
        if(CRC_8(&temp_array[3],2) == temp_array[5])            //进行CRC-8校验
        {
            temp_uint = temp_array[3]*256+temp_array[4];        //取出16位的湿度值
            temp_float = ((float)temp_uint)*0.152590;           //根据手册公式计算
            SHT30.ucHumidity = (uint8_t)(temp_float*0.01);      //除以100，得到正常湿度值
        }
    }
}

/*
* @name   CRC_8
* @brief  CRC-8校验
* @param  Crc_ptr -> 校验数据首地址
		LEN     -> 校验数据长度
* @retval CRC_Value -> 校验值      
*/
static uint8_t CRC_8(uint8_t *Crc_ptr,uint8_t LEN)
{
	uint8_t CRC_Value = 0xFF;
	uint8_t i = 0,j = 0;

	for(i=0;i<LEN;i++)
	{
		CRC_Value ^= *(Crc_ptr+i);
		for(j=0;j<8;j++)
		{
			if(CRC_Value & 0x80)
				CRC_Value = (CRC_Value << 1) ^ 0x31;
			else
				CRC_Value = (CRC_Value << 1);
		}
	}
	return CRC_Value;
}
/********************************************************
  End Of File
********************************************************/
